package main

import "fmt"

//设计一个支持 push ，pop ，top 操作，并能在常数时间内检索到最小元素的栈。
//
//
// push(x) —— 将元素 x 推入栈中。
// pop() —— 删除栈顶的元素。
// top() —— 获取栈顶元素。
// getMin() —— 检索栈中的最小元素。
//
//
//
//
// 示例:
//
// 输入：
//["MinStack","push","push","push","getMin","pop","top","getMin"]
//[[],[-2],[0],[-3],[],[],[],[]]
//
//输出：
//[null,null,null,null,-3,null,0,-2]
//
//解释：
//MinStack minStack = new MinStack();
//minStack.push(-2);
//minStack.push(0);
//minStack.push(-3);
//minStack.getMin();   --> 返回 -3.
//minStack.pop();
//minStack.top();      --> 返回 0.
//minStack.getMin();   --> 返回 -2.
//
//
//
//
// 提示：
//
//
// pop、top 和 getMin 操作总是在 非空栈 上调用。
//
// Related Topics 栈 设计
// 👍 757 👎 0


//leetcode submit region begin(Prohibit modification and deletion)
type MinStack struct {
	Val []int // 记录数组
	Min []int   // 记录当前最小值
	Len int
}




/** initialize your data structure here. */
func Constructor() MinStack {
	return MinStack{
		Val: []int{},
		Min: []int{},
		Len: 0,
	}
}


func (this *MinStack) Push(x int)  {
	this.Val = append(this.Val, x)
	if len(this.Min) > 0 {
		top := this.Min[this.Len - 1]
		if x < top {
			this.Min = append(this.Min, x)
		} else {
			this.Min = append(this.Min, top)
		}
	} else {
		// 空数组直接添加
		this.Min = append(this.Min, x)
	}

	this.Len++
}

// 出栈
func (this *MinStack) Pop()  {
	this.Val = this.Val[:this.Len - 1]
	this.Min = this.Min[:this.Len - 1]
	this.Len--
}


func (this *MinStack) Top() int {
	return this.Val[this.Len - 1]
}


func (this *MinStack) GetMin() int {
	return this.Min[this.Len - 1]
}


/**
 * Your MinStack object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Push(x);
 * obj.Pop();
 * param_3 := obj.Top();
 * param_4 := obj.GetMin();
 */
//leetcode submit region end(Prohibit modification and deletion)
func main() {
	// 输入：
	//["MinStack","push","push","push","getMin","pop","top","getMin"]
	//[[],[-2],[0],[-3],[],[],[],[]]
	//
	//输出：
	//[null,null,null,null,-3,null,0,-2]
	//
	//解释：

	minStack := Constructor()
	minStack.Push(-2)
	minStack.Push(0)
	minStack.Push(-1)
	fmt.Printf("%#v \n", minStack)
	min := minStack.GetMin()
	fmt.Println("min : ", min)
	minStack.Pop()
	top := minStack.Top()
	fmt.Println("top : ", top)
	min = minStack.GetMin()
	fmt.Println("min : ", min)
}
